/*

    This file is part of Blue Violin.

    Blue Violin is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Blue Violin is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero Public License for more details.

    You should have received a copy of the GNU Affero Public License
    along with Blue Violin.  If not, see <http://www.gnu.org/licenses/>.

    Blue Violin  Copyright (C) 2008  Blue Violin, Inc. & Josh Watts <josh.watts@blueviolin.org>
	For more information, visit http://www.blueviolin.org/

    This program comes with ABSOLUTELY NO WARRANTY.

*/


function BVReport()
{
	this.m_aSteps = new Array();
	this.m_dtStart = null;
	this.m_dtEnd = null;
	this.m_dtElapsed = null;
	this.m_sEmail = "";
	this.m_bFailed = false;

	this.Step = function(sAction, oAttributes)
	{
		this.m_sAction = sAction;
		this.m_oAttributes = oAttributes;
		this.m_nScreenID = -1;
	};


	$get("btnCloseReport").attachEvent("onclick",
									   BVReport.hide);

}


BVReport.initialize = function()
{
	var btnCloseReport = $get("btnCloseReport");
	btnCloseReport.attachEvent("onclick",
							   BVReport.hide);
};


BVReport.prototype.unhide = BVReport.unhide = function()
{
	$get("divReport").style.zIndex = "10";
	$get("divReport").style.display = "block";
	$get("spnBrowsers").style.display = "none";
	// $get("divHistory").style.display = "none";
	
};


BVReport.hide = function()
{
	$get("divReport").style.zIndex = "-1";
	$get("spnBrowsers").style.display = "block";
	// WindowResizer.resize();
};


BVReport.resize = function()
{
	var divReport = $get("divReport");
	var oTable = $get("tblReport");

	oTable.style.width = $get("divReportHeader").offsetWidth + "px";
};


BVReport.prototype.start = function()
{
 	var oStep = null;
	var i = 0;
	var nSteps = this.m_aSteps.length;
	for (i = 0;
		 i < nSteps;
		 ++i)
	{
		oStep = this.m_aSteps.pop();
		delete oStep;
	}
	this.m_dtStart = new Date();
	this.m_bFailed = false;
};
	

BVReport.prototype.Finish = function()
{
	this.m_dtEnd = new Date();
	this.m_dtElapsed = new Date(this.m_dtEnd.valueOf() - this.m_dtStart.valueOf());

	var oSaveReport = {};
	oSaveReport.start = this.m_dtStart;
	oSaveReport.end = this.m_dtEnd;
	oSaveReport.elapsed = this.m_dtElapsed;
	oSaveReport.result = this.m_bFailed;
	oSaveReport.steps = this.m_aSteps;
	
	var $oHttp = $http("POST", "scripts.php");
	$oHttp.send("action=savereport&result=" + this.m_bFailed.toString() + "&report=" + encodeURIComponent(oSaveReport.toJSONString()));
	
};


BVReport.prototype.addStep = function(sAction, oAttributes)
{
	if ("exception" == sAction)
	{
		this.m_bFailed = true;
	}
	var oStep = new this.Step(sAction, oAttributes);
	this.m_aSteps.push(oStep);
	return oStep;
};


BVReport.prototype.email = function()
{
	var oHttp = null;
	var sEmail = "";
	var bSendEmail = true;
	var sResult = "";

	sResult = (false == this.m_bFailed) ? 
		"Passed :) " :
		"Failed :( ";
	
	sEmail = "Result: " + sResult + "\n\n" +
		"Run Date: " + this.m_dtStart.toDateString() + " @ " + this.m_dtStart.toTimeString() + "\n\n" +
		"Run Time: " + this.m_dtElapsed.format() + "\n\n" +
		this.m_sEmail;

	if (true == window.oProfiles.get_emailOnlyOnFail())
	{
		if (true != this.m_bFailed)
		{
			bSendEmail = false;
		}
	}

	if (true == bSendEmail)
	{
		oHttp = $http("POST", "email.php");
		oHttp.send("&subject=Blue Violin replay report" +
				   "&body=" + encodeURIComponent(sEmail));
	}
};


BVReport.prototype.display = function(bEmailReport)
{
	this.unhide();
	//divReport.style.color = "black";
	var oRow = null;
	var oCell = null;
	var divTemp = null;
	var spnTemp = null;

	$get("divReportHeader").style.display = "block";


	$get("spnReportTitleMessage").innerHTML = "Script Replay Results";
	$get("spnResultMessage").innerHTML = (true == this.m_bFailed) ? "Failed" : "Passed";
	$get("spnResultMessage").className = (true == this.m_bFailed) ? "Failed" : "Passed";
	$get("imgResult").src = "images/reports/" + ((true == this.m_bFailed) ? 
												 "unhappy_24_n.gif" : 
												 "smiley_24_n.gif");
	$get("spnRunDateMessage").innerHTML = this.m_dtStart.toDateString() + " @ " + this.m_dtStart.toTimeString();
	$get("spnElapsedTimeMessage").innerHTML = this.m_dtElapsed.format();

	var oTable = $get("tblReport");
	oTable.deleteTHead();
	var nRows = oTable.rows.length;

	this.m_sEmail = "";

	for (var i = 0;
		 i < nRows;
		 ++i)
	{
		oTable.deleteRow(0);
	}

	for (var i = 0;
		 i < this.m_aSteps.length;
		 ++i)
	{
		var oStep = this.m_aSteps[i];
		var oAttributes = oStep.m_oAttributes;
		if (0 != i)
		{
			oRow = oTable.insertRow(-1);
			oRow.className = "ReportRowSeparator";
			oCell = this.createCell(oRow);
			oCell.colSpan = 2;
			oCell.className = "ReportCellSeperator";
			
		}
		oRow = oTable.insertRow(-1);
		oRow.className = (0 == (i % 2)) ? "ReportRow1" : "ReportRow2";
		switch (oStep.m_sAction)
		{
			case "click":
				this.displayClick(oStep, oRow, oAttributes);
				break;
				
			case "changebrowser":
				this.displayChangeBrowser(oStep, oRow, oAttributes);
				break;

			case "documentcomplete":
				this.displayDocumentComplete(oStep, oRow, oAttributes);
				break;

			case "documentselect":
				this.displayDocumentSelect(oStep, oRow, oAttributes);
				break;
				
			case "elementcheckpoint":
				this.displayElementCheckpoint(oStep, oRow, oAttributes);
				break;

			case "exception":
				this.displayException(oStep, oRow, oAttributes);
				break;

			case "keypress":
				this.displayKeyPress(oStep, oRow, oAttributes);
				break;
				
			case "navigate":
				this.displayNavigate(oStep, oRow, oAttributes);
				break;

		}
	}
	window.setTimeout(BVReport.resize, 50);
	if (false != bEmailReport)
	{
		this.email();
	}
};


BVReport.prototype.displayReportItem = function(oDisplay, oRow)
{
	var oBreak = null;
	var spnTitle = null;
	var spnValue = null;
	var oProp = null;
	var sTitle = "";
	
	oCell = this.createCell(oRow);

	spnTitle = $create("div");
	spnTitle.className = "ReportCellHeader";
	spnTitle.innerHTML = oDisplay.title;
	oCell.appendChild(spnTitle);

	sTitle = oDisplay.title;
	delete oDisplay.title;

	for (oProp in oDisplay)
	{
		if (Object.toJSONString === oDisplay[oProp])
		{
			continue;
		}
		spnTitle = $create("SPAN");
		spnTitle.className = "ReportCellProperty";
		spnTitle.innerHTML = oProp;
		spnValue = $create("SPAN");
		spnValue.className = "ReportCellValue";
		spnValue.innerHTML = oDisplay[oProp];
		oCell.appendChild(spnTitle);
		oCell.appendChild(spnValue);
		oBreak = $create("BR");
		oCell.appendChild(oBreak);
	}

	//oCell = this.createCell(oRow);

	// build report email
	this.m_sEmail += sTitle + "\n";
	for (oProp in oDisplay)
	{
		if (Object.toJSONString === oDisplay[oProp])
		{
			continue;
		}
		this.m_sEmail += oProp + ": " + oDisplay[oProp] + "\n";
	}
	this.m_sEmail += "\n";
};


BVReport.prototype.checkAttribute = function(sAttribute, 
											 oAttributes, 
											 sDisplayProperty,
											 oDisplay)
{
	if ("" !== oAttributes[sAttribute] &&
		"undefined" !== typeof oAttributes[sAttribute])
	{
		oDisplay[sDisplayProperty] = oAttributes[sAttribute];
	}
};


BVReport.prototype.createCell = function(oRow)
{
	var oCell = oRow.insertCell(-1);
	oCell.className = "ReportCell";
	return oCell;
};


BVReport.prototype.generateScreenUrl = function(nScreenID)
{
	return "<img src=\"images.php?action=get&imageid=" + nScreenID + "\"  />";		
};


BVReport.prototype.displayNavigate = function(oStep, oRow, oAttributes)
{
	var oDisplay = {};

	oDisplay.title = "Navigate";
	this.checkAttribute("URL", oAttributes, "URL", oDisplay);
	this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
	this.displayReportItem(oDisplay, oRow);
};


BVReport.prototype.displayChangeBrowser = function(oStep, oRow, oAttributes)
{
	var oDisplay = {};

	oDisplay.title = "Changed Browsers";
	this.checkAttribute("browser", oAttributes, "Browser", oDisplay);
	this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
	
	this.displayReportItem(oDisplay, oRow);
};

		
BVReport.prototype.displayClick = function(oStep, oRow, oAttributes)
{
	var spnTitle;
	var spnValue;
	var oBreak;
	var oDisplay = {};
	var oProp = null;

	switch (oAttributes.tagName.toUpperCase())
	{
		case "IMG":
			oDisplay.title = "Clicked on an image";
			oDisplay["Image URL"] = oAttributes.src;
			if ("undefined" != typeof(oAttributes.id))
			{
				oDisplay["ID"] = oAttributes.id;
			}
			if ("undefined" != typeof(oAttributes.id))
			{
				oDisplay["Message"] = oAttributes.passedMessage;
			}
			break;
			
		case "INPUT":
			switch (oAttributes.type.toUpperCase())
			{
				case "SUBMIT":
					oDisplay.title = "Clicked a button";
					this.checkAttribute("tagName", oAttributes, "Tag Name", oDisplay);
					this.checkAttribute("type", oAttributes, "Type", oDisplay);
					this.checkAttribute("id", oAttributes, "ID", oDisplay);
					this.checkAttribute("name", oAttributes, "Name", oDisplay);
					this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
					break;

				default:
					oDisplay.title = "Clicked an input";
					this.checkAttribute("tagName", oAttributes, "Tag Name", oDisplay);
					this.checkAttribute("type", oAttributes, "Type", oDisplay);
					this.checkAttribute("id", oAttributes, "ID", oDisplay);
					this.checkAttribute("name", oAttributes, "Name", oDisplay);
					this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
					break;
			}
			break;

		case "TEXTAREA":
			oDisplay.title = "Clicked on a text area";
			this.checkAttribute("id", oAttributes, "ID", oDisplay);
			this.checkAttribute("name", oAttributes, "Name", oDisplay);
			this.checkAttribute("value", oAttributes, "Value", oDisplay);
			if ("undefined" === typeof(oDisplay["Value"]))
			{
				oDisplay["Value"] = "";
			}
			break;

		default:
			oDisplay.title = "Clicked on an element";
			this.checkAttribute("tagName", oAttributes, "Tag", oDisplay);
			this.checkAttribute("id", oAttributes, "ID", oDisplay);
			this.checkAttribute("name", oAttributes, "Name", oDisplay);
			this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
			break;
	}

	this.displayReportItem(oDisplay, oRow);
};
		

BVReport.prototype.displayDocumentComplete = function(oStep, oRow, oAttributes)
{
	var sURL = null;
	var oDisplay = {};

	oDisplay.title = "Loaded URL";
	this.checkAttribute("URL", oAttributes, "URL", oDisplay);
	this.checkAttribute("Elapsed", oAttributes, "Load Time", oDisplay);
	this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
	
	this.displayReportItem(oDisplay, oRow);

// 	oCell = this.createCell(oRow);
// 	sURL = oAttributes["URL"];
// 	oCell.innerHTML = "<span class=\"ReportCellProperty\">Loaded URL</span><br />" +
// 	"<span class=\"ReportCellProperty\">URL</span>" + 
// 	"<span class=\"ReportCellValue\">" + sURL + "</span><br/>" + 
// 	"<span class=\"ReportCellProperty\">Load Time</span>" + 
// 	"<span class=\"ReportCellValue\">" + oAttributes["Elapsed"] + "</span>";
// 	oCell = this.createCell(oRow);
};

BVReport.prototype.emailDocumentComplete = function(oStep)
{
	var sEmail = "Loaded URL\n" +
		"URL: " + oStep.m_oAttributes["URL"] + "\n" +
		"Load Time: " + oStep.m_oAttributes["Elapsed"] + "\n\n";
	return sEmail;
};


BVReport.prototype.displayDocumentSelect = function(oStep, oRow, oAttributes)
{
	var oDisplay = {};
	
	oDisplay.title = "Checking for text on the page";
	this.checkAttribute("highlightedText", oAttributes, "Match", oDisplay);
	this.checkAttribute("found", oAttributes, "Found", oDisplay);
	this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
	
	this.displayReportItem(oDisplay, oRow);
};


BVReport.prototype.displayException = function(oStep, oRow, oAttributes)
{
	var oDisplay = {};
	
	oDisplay.title = "Replay failed";
	this.checkAttribute("message", oAttributes, "Reason", oDisplay);
	this.checkAttribute("failedMessage", oAttributes, "Message", oDisplay);
	
	this.displayReportItem(oDisplay, oRow);

// 	oCell = this.createCell(oRow);
// 	rexReplace = /\n/;
// 	oCell.innerHTML = "<b>Exception</b> - " + oAttributes.message.replace(rexReplace, "<br/>");
// 	oCell = this.createCell(oRow);
};


BVReport.prototype.emailException = function(oStep)
{
	var sEmail = "Exception\n" +
		oStep.m_oAttributes().message + "\n\n";
	return sEmail;
};


BVReport.prototype.displayKeyPress = function(oStep, oRow, oAttributes)
{
	var oDisplay = {};
	
	oDisplay.title = "You typed the following";
	this.checkAttribute("value", oAttributes, "Typed", oDisplay);
	this.checkAttribute("tagName", oAttributes, "Tag", oDisplay);
	this.checkAttribute("id", oAttributes, "ID", oDisplay);
	this.checkAttribute("name", oAttributes, "Name", oDisplay);
	this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
	this.displayReportItem(oDisplay, oRow);
};


BVReport.prototype.displayElementCheckpoint = function(oStep, oRow, oAttributes)
{
	var oDisplay = {};
	oDisplay.title = "Element Checkpoint found";
	this.checkAttribute("passedMessage", oAttributes, "Message", oDisplay);
	this.displayReportItem(oDisplay, oRow);

};



/*************************

Historical Reports

*/


BVReport.prototype.showHistoricalReport = function()
{
	var oHttp = $http("POST", "scripts.php");
	var sReports = "";
	var oReports = null;
	var divHistory = $get("divHistory");
	var divHistoryItems = $get("divHistoryItems");
	var divTemp = null;
	var dtTemp = null;
	var i = 0;
	var imgResult = null;
	var spnDate = null;
	var spnTime = null;

	this.unhide();
	//$get("divReplayResults").style.display = "none";
	divHistory.style.display = "block";
	divHistoryItems.innerHTML = "";

	$get("spnReportTitleMessage").innerHTML = "Past Replay Information";

	oHttp.send("action=gethistoricalreportlist");
	sReports = oHttp.responseText;

	oReports = sReports.parseJSON();

	for (i = 0;
		 i < oReports.length;
		 ++i)
	{
		divTemp = $create("DIV");
		divTemp.className = "HistoryItem";
		

		imgResult = $create("IMG");
		if (0 == oReports[i].result)
		{
			imgResult.src = "images/reports/green_round_16_n.gif";
		}
		else
		{
			imgResult.src = "images/reports/red_round_16_n.gif";
		}
		imgResult.className = "HistoryItemImage";
		divTemp.appendChild(imgResult);		


		spnDate = $create("SPAN");
		dtTemp = new Date(Date.parse(oReports[i].timestamp));
		spnDate.innerHTML = dtTemp.toDisplay();
		spnDate.className = "HistoryItemDate";
		divTemp.appendChild(spnDate);

		spnTime = $create("SPAN");
		spnTime.innerHTML = dtTemp.toTimeDisplay();
		spnTime.className = "HistoryItemTime";
		divTemp.appendChild(spnTime);

		divTemp.id = oReports[i].report_guid;
		
		divTemp.attachEvent("onclick",
							$createDelegate(this, this.displayHistoryReport));

		divHistoryItems.appendChild(divTemp);
		
	}

};


BVReport.prototype.displayHistoryReport = function()
{

	var oElement = window.event.srcElement;
	var oHttp = null;
	var sJson = null;
	var oReport = null;
	var i = 0;


	if ("DIV" != oElement.tagName)
	{
		oElement = oElement.parentNode;
	}
	oHttp = $http("POST", "scripts.php");
	oHttp.send("action=getreport&guid=" + oElement.id);
	sJson = oHttp.responseText;

	oReport = sJson.parseJSON();
	this.m_dtStart = new Date(Date.parse(oReport.start));
	this.m_dtEnd = new Date(Date.parse(oReport.end));
	this.m_dtElapsed = new Date(Date.parse(oReport.elapsed));
	this.m_bFailed = oReport.result;
	this.m_aSteps = oReport.steps;
	for (i = 0;
		 i < this.m_aSteps.length;
		 ++i)
	{
		//this.m_aSteps[i].prototype = 
		
	}
	
	this.display(false);

};

	

BVReport.prototype.populateCalendar = function()
{
	var dtNow = new Date();
	var aMonths = ["January",
				   "February",
				   "March",
				   "April",
				   "May",
				   "June",
				   "July",
				   "August",
				   "September",
				   "October",
				   "November",
				   "December"];
	var aDays = ["Sunday",
				 "Monday",
				 "Tuesday",
				 "Wednesday",
				 "Thursday",
				 "Friday",
				 "Saturday"];
	var nMonth = dtNow.getMonth();
	var nDate = dtNow.getDate();
	var nDayOfWeek = dtNow.getDay();
	var nYear = dtNow.getFullYear();
	var dtFirstOfMonth = new Date(nYear, nMonth, 1);
	var aRow = $get("tbodyCalendar").rows(0);
	var i = 0;
	var nCalDay = 1;
	var nDaysInMonth = 32 - new Date(nYear, nMonth, 32).getDate();
	var nRows = 0;

	$get("tdCalendarLabel").innerHTML = aMonths[nMonth] + "&nbsp;" + nYear.toString();
	

	for (i = 0;
		 i < dtFirstOfMonth.getDay();
		 ++i)
	{
		aRow.cells(i).innerHTML = "&nbsp;";
	}
	for (i;
		 i < 7;
		 ++i)
	{
		aRow.cells(i).innerHTML = nCalDay++;
	}
	nRows = 1;
	aRow = $get("tbodyCalendar").rows(nRows++);
	while (true)
	{
		for (j = 0;
			 j < 7;
			 ++j)
		{
			if (nCalDay <= nDaysInMonth)
			{
				aRow.cells(j).innerHTML = nCalDay++;
			}
			else
			{
				aRow.cells(j).innerHTML = "&nbsp;";
			}
			
		}
		if (nCalDay >= nDaysInMonth)
		{
			break;
		}
		aRow = $get("tbodyCalendar").rows(nRows++);
	}



};

	



